/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2009-2020 Rock Mao
* creator : Rock Mao
* created : 2009-5-2   22:29
* filename: LaborRenderSystem.h
-----------------------------------------------------------------------------
*/
#ifndef __LABORENDERSYSTEM_H__
#define __LABORENDERSYSTEM_H__

#include "LaborCoreDef.h"
#include "../include/Math/LaborMathInclude.h"
#include "LaborHardwareBuffer.h"
#include "LaborIndexBuffer.h"
#include "LaborVertexBuffer.h"
#include "Labor2DRectRenderableObject.h"
#include "LaborConstantBuffer.h"
#include "LaborRenderState.h"
#include "LaborGPUProgram.h"
#include "LaborInputLayout.h"
NAMESPACE_LABOR3D_BEGIN

#define IL_PT    L"PT"

class CLTexture;
class ILInputLayout;
class ILShader;
class LABORCORE_API CLRenderSystem
{
protected:
	float      m_f2DZValue;
public:
	CLRenderSystem();
	virtual ~CLRenderSystem();

	virtual void destroy() = 0;
	virtual const CLString& getName(void) const = 0;

	//// for render 
	void makeProjectionMatrix( float left, float right, float bottom, float top, float nearPlane, float farPlane, CLMatrix4x4 &matrixProjection );
	// Sets frustum by FOV in degrees along the horizontal axis
	void makeProjectionMatrix( float FOVx, float aspectRatio, float nearPlane, float farPlane, CLMatrix4x4 &matrixProjection );
	// Viewport methods
	virtual void setViewport( int x, int y, int width, int height ) = 0;
	virtual void getViewport( int& x, int& y, int& width, int& height ) const = 0;
	virtual float getViewportPixelWidth() const  = 0;
	virtual float getViewportPixelHeight() const = 0;
	
	//// 
	virtual bool          initDevice( int hWnd ) = 0;
	virtual bool          cleanUpDevice() = 0;
	virtual void*         getInst() = 0;
	virtual void          clearBackBuffer( float r, float g, float b, float a ) = 0;
	virtual void          present( int x, int y ) = 0;
	virtual void          drawIndexed( int indexCount, int indexStart, int baseVertex ) = 0;

	virtual void          drawRect( CLTexture *pTexture, CLRectF & destRect, CLRectF & srcRect, CLColor_4f& _color ) = 0;
	virtual void          drawRect( CLTexture *pTexture, CLRectF & destRect, CLColor_4f& _color ) = 0;

	///@down for buffer
	virtual CLVertexBuffer*    createVertexBuffer(size_t vertexSize, size_t numVerts, EHB_Usage usage, bool useShadowBuffer = false) = 0;
	virtual CLIndexBuffer*     createIndexBuffer(eLIndexType itype, size_t numIndexes, EHB_Usage usage, bool useShadowBuffer = false) = 0;
	virtual CLConstantBuffer*  createConstantBuffer(size_t buffer_size) = 0;
	virtual ILSamplerState*    createSamplerState( const wchar_t * _name ) = 0;
	virtual ILSamplerState*    createSamplerState( const sLSamplerStateDesc & _desc ) = 0;

	virtual ILShader*          createShader(const wchar_t* shaderName , eLShaderType type)= 0;
	virtual ILInputLayout*     createInputLayout(const wchar_t* name , CLInputLayoutDesc& desc) = 0;

	/// --------------------------------------------
	virtual void setVertexBuffer(UINT nStart, UINT nNumberBuffers, CLVertexBuffer *vBuffer, const UINT *pStrides, const UINT *pOffsets) = 0;
	virtual void setIndexBuffer( CLIndexBuffer *pBuffer, eLIndexType eIdxType, UINT Offset = 0) = 0;
	virtual void setPrimitiveTopology( eLPrimitiveTopology ePrimitiveTopology)= 0;
	virtual bool setInputLayout( const wchar_t *pLayout )                     = 0;
	virtual bool setInputLayout( ILInputLayout* pInputLayout)                 = 0;
	virtual bool setSamplerState(int nSlot, ILSamplerState *pSamplerState)    = 0;
	virtual ILInputLayout* getCurInputLayout()                                = 0;
	virtual ILInputLayout* getInputLayout( const wchar_t * layout_name)       = 0;
	///@up for buffer

	virtual void begin() = 0;
	virtual void end()   = 0;
	virtual void begin2D( int width = 0, int height = 0 ) = 0;
	virtual void beginPerspective2D( float zValue = 1000.0f, int width = 0, int height = 0) = 0;
	virtual void end2D() = 0;

	///@ GPU program
	virtual bool setVertexShader( ILShader *pVertexShader ) = 0;
	virtual bool setPixelShader( ILShader *pPixelShader)    = 0;
	virtual bool setGeometryShader(ILShader *pGeomShader)   = 0;
	
	virtual ILGpuProgram* createGPUProgram()                = 0;
	virtual bool setGPUProgram(ILGpuProgram* pGpuProgram)   = 0;
	///@ up 

	virtual void  setWorldMatrix(float* _World) = 0;
	virtual void  setViewMatrix(float* _View) = 0;
	virtual void  setProMatrix(float* _Pro) = 0;

	virtual void  setWorldMatrix(CLMatrix4x4& _matWorld) = 0;
	virtual void  setViewMatrix(CLMatrix4x4& _matView) = 0;
	virtual void  setProMatrix(CLMatrix4x4& _matPro) = 0;

	/// temp code

	virtual void *getDevice() = 0;
	virtual void  setShaderPath( const wchar_t * strPath ) = 0;
	virtual void  setTexturePath( const wchar_t * strPath ) = 0;

	virtual void setTexture( CLTexture *pTexture, int layer = 0 ) = 0;
	virtual CLTexture *  createTextureFromFile( const wchar_t * filename ) = 0;
	float        get2DZValue()               { return m_f2DZValue; }
	void         set2DZValue( float _value ) { m_f2DZValue = _value; }
	virtual void getCanvasSize(int& w , int & h) = 0;


};
NAMESPACE_LABOR3D_END
#endif